home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / asm / alib11b.zip / CODE1.ZIP / DISKINFO / FILES.ASM < prev    next >
Assembly Source File  |  1994-10-04  |  13KB  |  408 lines

  1. COMMENT ~
  2. FILES.ASM -- File manipulation Procedures
  3.  
  4.    From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
  5.          by Christopher L. Morgan
  6.          Copyright (C) 1984 by The Waite Group, Inc.
  7.  
  8.    Contents:
  9.    ---------
  10.    CBUF_CLR    --  Clear the circular buffer
  11.    CBUF_IN    --  Input to circular buffer 
  12.    CBUF_INIT    --  Initialize a circular buffer
  13.    CBUF_OUT    --  Output to a circular buffer
  14.    CBUF_PUT    --  Put a byte into a circular buffer
  15.    CLOS_FIL    --  Close a file
  16.    EMSG_OUT    --  Exception message output
  17.    FILT_CR*    --  Filter for carriage return/linefeed
  18.    MAKE_FIL    --  Create a file
  19.    READ_FIL    --  Read bytes from a file
  20.    SAVE        --  Save a file from communications line to disk
  21.    WRIT_FIL    --  Write bytes to a file
  22.  
  23.   Overview: These routines require MS/PCDOS 2.+, because they use file handles
  24.     & filters.
  25.     EMSG_OUT reports exceptions to the user.  These codes are extended
  26.     from standard DOS (0,14,19,20,21,&22).
  27.     GET_SPEC gets parameters from the command line, and places
  28.     them where you specify.
  29.     The xxxx_FIL routines are standard and self-explanatory.
  30.     The CBUF_xxxx routines handle input/output for a circular buffer.
  31.     There are four variables and three constants associated with CBUF_xxxx.
  32.     The variables are CBUF & GUAGE (memory variables), an input pointer held
  33.     in DI, and an output pointer held in SI. CBUF is the base address of the
  34.     buffer and GUAGE is the number of items currently in the buffer. As items
  35.     are added to the buffer, they are placed according to DI, and DI is
  36.     incremented to account for them. As items are removed from the buffer,
  37.     they are taken according to SI, and SI is incremented accordingly. The
  38.     CBUF_xxxx constants are BUF_SIZ, NEAREMPTY, & NEARFULL.  BUF_SIZ is the
  39.     total # of bytes allotted to the buffer. NEARFULL & NEAREMPTY are limits
  40.     to how few or many items should be in the buffer at one time. NEARFULL
  41.     helps to prevent buffer overflow. When the buffer hits NEARFULL, the
  42.     routines call a routine to stop the input.  Programmer must adjust NEARFULL
  43.     according to input speed. NEAREMPTY is the trigger to start input again
  44.     after a NEARFULL condition.
  45.      The SAVE routine saves files from one of the two communications lines
  46.     to the disk.  It uses the CBUFF routines.
  47.     COUNT, FILT_WS, & FILT_CR are filters. COUNT counts the number of 
  48.      characters and words in a file. FILT_WS replaces any single CR/LF with a
  49.      `soft' CR/LF, and any double CR/LF with a `soft' and `hard' CR/LF pair.
  50.      FILT_CR strips bit 7 from each byte, adds LF's to CR's, and expands TAB's.
  51.      All these filter programs can serve as models for new filter programs. 
  52.  
  53.  ------------------------------------------------------------------------------
  54.   It is better to put this data in the source code calling these routines, and
  55.     then comment out this section.                         
  56. ~
  57. DATAS    SEGMENT    PUBLIC
  58.     CR    EQU    0DH            ;ASCII code for carriage return
  59.     LF    EQU    0AH            ;ASCII code for linefeed
  60.     CTRL_Z    EQU    1AH            ;ASCII code for ^Z
  61.     BLK_SIZ   =    0            ;K=block size
  62.     CBUF_SIZ      DW    256             ;K=CBUF max capacity
  63.     CBUF         DB    1        ;K=base address of CBUF
  64.     LBUF        DB    256 DUP('LBUF')
  65.     NAME_BUF    DB    64 DUP('NAME')
  66. ;
  67. ;Following table used by EMSG_OUT
  68.     EMSG    DW    EMSG1
  69.         DW    EMSG2
  70.         DW    EMSG3
  71.         DW    EMSG4
  72.         DW    EMSG5
  73.         DW    EMSG6
  74.         DW    EMSG7
  75.         DW    EMSG8
  76.         DW    EMSG9
  77.         DW    EMSG10
  78.         DW    EMSG11
  79.         DW    EMSG12
  80.         DW    EMSG13
  81.         DW    EMSG14
  82.         DW    EMSG15
  83.         DW    EMSG16
  84.         DW    EMSG17
  85.         DW    EMSG18
  86.     EMSG1    DB    CR,LF,'Invalid function number',CR,LF,0 
  87.     EMSG2    DB    CR,LF,'File not found',CR,LF,0
  88.     EMSG3    DB    CR,LF,'Path not found',CR,LF,0
  89.     EMSG4    DB    CR,LF,'Too many open files',CR,LF,0 
  90.     EMSG5    DB    CR,LF,'Access denied',CR,LF,0
  91.     EMSG6    DB    CR,LF,'Invalid handle',CR,LF,0
  92.     EMSG7    DB    CR,LF,'Memory control blocks destroyed',CR,LF,0
  93.     EMSG8    DB    CR,LF,'Insufficient memory',CR,LF,0
  94.     EMSG9    DB    CR,LF,'Invalid memory block address',CR,LF,0
  95.     EMSG10  DB    CR,LF,'Invalid environment',CR,LF,0
  96.     EMSG11    DB    CR,LF,'Invalid format',CR,LF,0
  97.     EMSG12    DB    CR,LF,'Invalid access code',CR,LF,0
  98.     EMSG13    DB    CR,LF,'Invalid data',CR,LF,0
  99.     EMSG14    DB    CR,LF,'Message not in use',CR,LF,0
  100.     EMSG15    DB    CR,LF,'Invalid drive was specified',CR,LF,0
  101.     EMSG16    DB    CR,LF,'Attempted to remove the current directory',CR,LF,0
  102.     EMSG17    DB    CR,LF,'Not same device',CR,LF,0
  103.     EMSG18    DB    CR,LF,'No more files',CR,LF,0
  104. DATAS    ENDS 
  105. ;------------------------------------------------------------------------------
  106. CODES    SEGMENT
  107. ;The following variables/constants must be defined in the source code calling
  108. ;  these routines.
  109.  
  110.     EXTRN    COM_INCK:FAR,COM_INIT:FAR,COM_ON:FAR,COM_OFF:FAR,MSG_OUT:FAR
  111.     EXTRN    DTA:DWORD,LAST:BYTE,GAUGE:WORD,NEARFULL:WORD,NEAREMPTY:BYTE
  112.  
  113.     PUBLIC    EMSG_OUT,GET_SPEC,MAKE_FIL,CLOS_FIL,WRIT_FIL,READ_FIL
  114.     PUBLIC    CBUF_INIT,CBUF_PUT,CBUF_IN,CBUF_CLR,CBUF_OUT,SAVE
  115.  
  116. ASSUME CS:CODES,DS:DATAS
  117. ;----------------------------I/O ROUTINES--------------------------------------
  118. ;Routine to send out exception messages
  119. EMSG_OUT    PROC    FAR
  120.     PUSH    SI                ;Save registers
  121.     PUSH    AX
  122.     ADD    AX,AX                ;Double to index through table
  123.     MOV    SI,AX                ;SI points into table
  124.     MOV    SI,EMSG[SI]            ;Look up address of message
  125.     CALL     MSG_OUT                ;Send the message
  126.     POP    AX                ;Restore registers
  127.     POP    SI
  128.     RET
  129. EMSG_OUT    ENDP
  130. ;------------------------------------------------------------------------------
  131. ;Routine to get a file specifier 
  132. ;
  133. GET_SPEC    PROC    FAR
  134.     PUSH    DS                ;Save registers
  135.     PUSH    ES
  136.     PUSH    SI
  137.     PUSH    DI
  138.     PUSH    CX
  139. ;
  140. ;Set up pointer to DTA    to get parameters
  141.     LDS    SI,DTA                ;Point to DTA for parameters
  142.     MOV    CL,[SI]                ;Get length of string
  143.     MOV    CH,0                ;Make 16-bit
  144.     INC    SI                ;Skip the length byte
  145.     MOV    AL,' '                ;Scan past the spaces    
  146. GET_SPEC1:
  147.     CMP    [SI],AL                ;Check for space
  148.     JNE    GET_SPEC2            ;Exit loop if nonspace
  149.     INC    SI                ;Else point to next byte
  150.     LOOP    GET_SPEC1            ;Loop back for more
  151.     JCXZ    GET_SPEC3            ;No file specifier?
  152. ;
  153. ;Move the rest into place
  154. GET_SPEC2:
  155.     MOV    DI,DX                ;Index points to destination
  156.     CLD                    ;Forward direction
  157.     REP    MOVSB                ;Make the transfer
  158.     CLC                    ;No error, so no carry
  159.     JMP    GET_SPEC_XIT            ; and return
  160. GET_SPEC3:
  161.     MOV    AX,20                ;No file specified
  162.     STC                    ;Set carry for error
  163.     JMP    GET_SPEC_XIT            ; and exit
  164. GET_SPEC_XIT:
  165.     POP    CX                ;Restore registers
  166.     POP    DI
  167.     POP    SI
  168.     POP    ES
  169.     POP    DS
  170.     RET
  171. GET_SPEC    ENDP
  172. ;------------------------------------------------------------------------------
  173. ;Routine to create a file
  174. ;
  175. MAKE_FIL    PROC    FAR
  176.     PUSH    CX                ;Save register
  177.     MOV    CX,0                ;Attribute 0
  178.     INT    21H                ;DOS call
  179.     POP    CX                ;Restore register
  180.     RET
  181. MAKE_FIL    ENDP
  182. ;------------------------------------------------------------------------------
  183. ;Routine to close a file 
  184. ;
  185. CLOS_FIL    PROC    FAR
  186.     MOV    AH,3EH                ;Close a file
  187.     INT    21H                ;DOS call
  188.     RET
  189. CLOS_FIL    ENDP
  190. ;------------------------------------------------------------------------------
  191. ;Routine to write bytes to a file
  192. ;
  193. WRIT_FIL    PROC    FAR
  194.     MOV    AH,40H                ;Write to a file
  195.     INT    21H                ;DOS call
  196.     CMP    AX,CX                ;Was it all written?
  197.     JE    WRIT_FIL_XIT            ;Skip if yes
  198.     MOV    AX,21                ;Not all bytes were transferred
  199.     STC                    ;Set carry for error
  200. WRIT_FIL_XIT:
  201.     RET
  202. WRIT_FIL    ENDP
  203. ;------------------------------------------------------------------------------
  204. ;Routine to read bytes from a file
  205. ;
  206. READ_FIL    PROC    FAR
  207.     MOV    AH,3FH                ;Read from a file
  208.     INT    21H                ;DOS call
  209.     CMP    AX,CX                ;Everything back?
  210.     JE    READFIL_XIT            ;Skip if yes
  211.     MOV    AX,22                ;Not all read
  212.     STC                    ;Set carry for error
  213. READFIL_XIT:
  214.     RET
  215. READ_FIL    ENDP
  216. ;------------------------------------------------------------------------------
  217. ;Routine to handle input for a circular buffer 
  218. ;
  219. CBUF_INIT    PROC    FAR
  220.     MOV    SI,0                ;Initialize SI
  221.     MOV    DI,0                ;Initialize DI
  222.     MOV    GAUGE,0                ; and # of bytes in buffer
  223.     MOV    LAST,0                ; and last byte buffer
  224.     RET
  225. CBUF_INIT    ENDP
  226. ;------------------------------------------------------------------------------
  227. ;Routine to one byte into a circular buffer 
  228. ;
  229. CBUF_PUT    PROC    FAR
  230.     PUSH    DX                ;Save register
  231.     MOV    DX,GAUGE            ;Put V Guage in DX
  232.     MOV    CBUF[DI],AL            ;Put the byte into the buffer
  233.     INC    DI                ;Adjust pointer to next char
  234.     CMP    DI,CBUF_SIZ            ;Wrap it around?
  235.     JNE    CBUF_PUT1            ;Skip if no wrap
  236.     MOV    DI,0                ;Wraps back to zero
  237. CBUF_PUT1:
  238.     INC    DX                ;Count the character
  239.     CMP    DX,NEARFULL            ;Too many characters?
  240.     JNE    CBUF_PUT_XIT            ;Skip if not
  241.     CALL     COM_OFF                ;Request to stop flow
  242. CBUF_PUT_XIT:
  243.     POP    DX                ;Restore register
  244.     RET
  245. CBUF_PUT    ENDP
  246. ;------------------------------------------------------------------------------
  247. ;Routine to handle input to a circular buffer
  248. ;
  249. CBUF_IN    PROC    FAR
  250.     CALL    COM_INCK            ;Check for a character
  251.     JZ    CBUF_IN_XIT            ;Good exit if none
  252.     AND    AL,7FH                ;Strip off parity bit
  253.     CMP    AL,10                ;Check for <LF> (ASCII 10)
  254.     JNE    CBUF_IN1            ;Skip if not <LF>
  255.     CMP    LAST,13                ;Check for <CR> (ASCI 13)
  256.     JE    CBUF_IN2            ;Skip if CR/LF
  257. CBUF_IN1:
  258.     CALL    CBUF_PUT            ;Put byte into buffer
  259.     MOV    LAST,AL                ;Update last byte
  260. CBUF_IN2:
  261.     CMP    AL,13                ;Check for <CR>
  262.     JNE    CBUF_IN3            ;Skip if not
  263. ;
  264. ;Insert LF if character was <CR>
  265.     PUSH    AX                ;Save the current character
  266.     MOV    AL,10                ;<LF>
  267.     CALL    CBUF_PUT            ; goes into buffer
  268.     POP    AX                ;Restore current character
  269. ;
  270. ;Check for end of file
  271. CBUF_IN3:
  272.     CMP    AL,CTRL_Z            ;Check for ^-Z (1AH)
  273.     JE    CBUF_IN5            ;EOF is an exception
  274. ;
  275. ;Check for overflow
  276.     PUSH    DX                ;Save register
  277.     MOV    DX,GAUGE            
  278.     CMP    DX,NEARFULL            ;Overflow of characters?
  279.     JL    CBUF_IN4            ;Skip if not
  280.     CALL    COM_OFF                ;Stop flow request
  281.     JMP    CBUF_IN_XIT            ;Good exit
  282. CBUF_IN4:                    ;No overflow
  283.     CALL    COM_ON                ;Make sure flow is on
  284.     JMP    CBUF_IN_XIT            ;Good exit
  285. CBUF_IN5:                    ;EOF exception handling
  286.     MOV    AX,19                ;EOF exception code
  287.     STC                    ;Set carry for exception
  288.     JMP    CBUF_IN_RET            ;Return with exception
  289. CBUF_IN_XIT:
  290.     POP    DX
  291.     CLC                    ;Clear carry -- no exception
  292. CBUF_IN_RET:
  293.     RET
  294. CBUF_IN    ENDP
  295. ;------------------------------------------------------------------------------
  296. ;Routine to flush a circular buffer 
  297. ;
  298. CBUF_CLR    PROC    FAR
  299.     PUSH    DI                ;Save registers
  300.     PUSH    DX
  301.     PUSH    CX
  302. ;
  303. ;Get the bytes from the buffer
  304.     MOV    CX,GAUGE            ;Get the count
  305.     JCXZ    CBUF_CLR_XIT            ;Check for empty
  306.     MOV    DI,0                ;Initialize destination
  307. ;
  308. ;Loop to get all the bytes
  309. CBUF_CLR1:
  310.     MOV    AL,CBUF[SI]            ;Get the character
  311.     INC    SI                ;Increment the pointer
  312.     CMP    SI,CBUF_SIZ            ;Wrap it?
  313.     JNE    CBUF_CLR2            ;Skip if no wrap
  314.     MOV    SI,0                ;Wrap the buffer pointer
  315. CBUF_CLR2:
  316.     MOV    LBUF[DI],AL            ;Put the byte in linear buffer
  317.     INC    DI
  318.     LOOP    CBUF_CLR1            ;Loop until all bytes in LBUF
  319. ;
  320. ;Send the linear buffer to the disk
  321.     MOV    CX,GAUGE            ;This is the number of bytes
  322.     LEA    DX,LBUF                ;Here is where they are
  323.     CALL    WRIT_FIL            ;Send them out
  324.     MOV    GAUGE,0                ;Set circular buffer empty
  325. CBUF_CLR_XIT:
  326.     POP    CX                ;Restore registers
  327.     POP    DX    
  328.     POP    DI
  329.     RET
  330. CBUF_CLR    ENDP
  331. ;------------------------------------------------------------------------------
  332. ;Routine to handle output from a circular buffer 
  333. ;
  334. CBUF_OUT    PROC    FAR
  335.     CMP    GAUGE,BLK_SIZ            ;Any characters?
  336.     JL    CBUF_OUT_XIT            ;If no, go
  337. ;
  338. ;Empty the buffer
  339.     CALL    COM_OFF                ;Hold the com line
  340.     CALL    CBUF_CLR            ;Clear the buffer
  341.     JC    CBUF_OUT_RET            ;Error?
  342. CBUF_OUT_XIT:
  343.     CLC                    ;Clear carry -- no exception
  344. CBUF_OUT_RET:
  345.     RET
  346. CBUF_OUT    ENDP
  347. ;------------------------------------------------------------------------------
  348. ;Routine to save a file from a communications line to disk 
  349. ;
  350. SAVE    PROC    FAR
  351. ;
  352. ;Set up return
  353.     PUSH    DS                ;Save for proper return
  354.     MOV    AX,0                ;Point to beginning of segment
  355.     PUSH    AX                ; for the offset
  356. ;
  357. ;Set up segments
  358.     MOV    DX,DS                ;PSP was data segment
  359.     MOV    AX,DATAS            ;New data segment
  360.     MOV    DS,AX                ;Put in DS
  361.     MOV    ES,AX                ; and in ES
  362.     MOV    WORD PTR DTA+2,DX        ;Set the segment of the data
  363. ;
  364. ;Set up the file
  365.     LEA    DX,NAME_BUF            ;Point to the ASCIIZ buffer
  366.     CALL    GET_SPEC            ;Get file specifications
  367.     JC    EXCEPTION            ;Error?
  368.     LEA    DX,NAME_BUF            ;ASCIIZ buff had file specs
  369.     CALL    MAKE_FIL            ;Set up the file
  370.     JC    EXCEPTION            ;Error?
  371.     MOV    BX,AX                ;Get the file handle
  372. ;
  373. ;Set up the communications line
  374.     MOV    DX,1                ;For COM1:
  375.     MOV    AL,0BBH                ;2400,E,8,1
  376.     CALL    COM_INIT            ;Initialize it
  377.     CALL    COM_ON                ; & turn it on
  378.     CALL    CBUF_INIT            ;Initialize the circular buffer
  379.     MOV    DX,1                ;COM_2:
  380. ;
  381. ;Main loop for pulling in bytes
  382. SAV_LOOP:
  383.     CALL    CBUF_IN                ;Check for input
  384.     JC    EXCEPTION            ;Error or EOF?
  385.     CALL    CBUF_OUT            ;Check to send it out
  386.     JC    EXCEPTION            ;Error?
  387.     JMP    SAV_LOOP
  388. EXCEPTION:                    ;Error/Exception handler
  389.     CMP    AX,19                ;EOF?
  390.     JE    SAV_1                ;If so, close it up & return
  391.     CALL    EMSG_OUT            ;Else report exception
  392.     JMP    SAV_XIT                ; and return
  393. SAV_1:                        ;Normal return
  394.     CALL    COM_OFF                ;Com line off
  395.     CALL    CBUF_CLR            ;Clear the circular buffer
  396.     JC    EXCEPTION            ;Error?
  397.     CALL    CLOS_FIL            ;Close the file
  398.     JC    EXCEPTION            ;Error?
  399.     JMP    SAV_XIT                ;Exit
  400. SAV_XIT:
  401.     CALL    COM_ON                ;Turn on com line
  402.     RET    
  403. SAVE    ENDP
  404. ;------------------------------------------------------------------------------
  405. CODES    ENDS
  406. ;
  407.     END
  408.